
package cz.muni.fi.pa165.carparkweb.actionbeans;

import cz.muni.fi.pa165.carpark.EmployeePosition;
import cz.muni.fi.pa165.carpark.TO.BusinessTripTO;
import cz.muni.fi.pa165.carpark.TO.EmployeeTO;
import cz.muni.fi.pa165.carpark.TO.VehicleTO;
import cz.muni.fi.pa165.carpark.servicies.BusinessTripService;
import cz.muni.fi.pa165.carpark.servicies.EmployeeService;
import cz.muni.fi.pa165.carpark.servicies.VehicleService;
import java.util.Date;
import java.util.List;
import net.sourceforge.stripes.action.*;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author xmarton1
 */
@UrlBinding("/employee/{$event}/{employee.id}")
public class EmployeeActionBean implements ActionBean {
    
    
    final static Logger log = LoggerFactory.getLogger(EmployeeActionBean.class);
    private ActionBeanContext context;

    @SpringBean
    protected EmployeeService employeeService;   
    @SpringBean
    protected BusinessTripService businessTripService;
    @SpringBean
    protected VehicleService vehicleService;
    
    @ValidateNestedProperties(value = {
            @Validate(on = {"create" }, field = "name", required = true, minlength= 1), 
    })
    private EmployeeTO employee;
    
    @ValidateNestedProperties(value = { 
            @Validate(on = {"createTrip"}, field = "vehicle.id", required = true)   
    }) 
    private BusinessTripTO businessTrip;
    
    @Validate(required=true, on="getTripsByDates")
    private Date fromDate;
    @Validate(required=true, on="getTripsByDates")
    private Date toDate;
    
    @Validate(required=true, on="cancel2", minvalue=1)
    private int drivenKms;

    public int getDrivenKms() {
        return drivenKms;
    }

    public void setDrivenKms(int drivenKms) {
        this.drivenKms = drivenKms;
    }

    public Date getFromDate() {
        return fromDate;
    }

    public void setFromDate(Date fromDate) {
        this.fromDate = fromDate;
    }

    public Date getToDate() {
        return toDate;
    }

    public void setToDate(Date toDate) {
        this.toDate = toDate;
    }

    public BusinessTripTO getBusinessTrip() {
        return businessTrip;
    }

    public void setBusinessTrip(BusinessTripTO businessTrip) {
        this.businessTrip = businessTrip;
    }
    
    private boolean wasError = false;
    private String errorName = "";
    
    public boolean getWasError(){
        if(wasError){
            wasError = false;
            return true;
        }
        return false;
    }
    
    public String getErrorName(){
        return errorName;
    }
    
    @Validate(required=true, on="getByPosition")
    private EmployeePosition employeePosition;
    public EmployeePosition getEmployeePosition(){
        log.debug("get Employee postion ={}",this.employeePosition);
        return this.employeePosition;
    }
    
    public void setEmployeePosition(EmployeePosition employeePosition){
        log.debug("set employee position:{}",employeePosition);
        this.employeePosition = employeePosition;
    }
    
    public Resolution getByPosition(){
        log.debug("getByPosition({})",this.employeePosition);
        return new ForwardResolution("/WEB-INF/jsp/employee.jsp");
    }
    
    @DontValidate()
    public Resolution listTripsForEmployee() {
        log.debug("Listing trips for " + employee);
        return new ForwardResolution("/WEB-INF/jsp/businessTripForEmployee.jsp");
    }
    
    @DefaultHandler
    public Resolution all() {
        log.debug("all()");
        return new ForwardResolution("/WEB-INF/jsp/employee.jsp");
    }
    
    public Resolution add() {
        log.debug("add employee");        
        return new ForwardResolution("/WEB-INF/jsp/employeeCreate.jsp");
    }
    
    public Resolution create(){
        log.debug("create employee={}",employee);
        employeeService.createEmp(employee);
        return new RedirectResolution(this.getClass(),"all");
    }
    
    public Resolution delete() {
        log.debug("delete({})",employee.getId());
        employee = employeeService.retrieveEmp(employee.getId());
        if(businessTripService.retriveEmployeeBusinessTrips(employee).isEmpty())
        {
            employeeService.deleteEmp(employee);
            return new RedirectResolution(this.getClass(),"all");
        }
        wasError = true;
        errorName = employee.getName();
        return new ForwardResolution(this.getClass(),"all");
    }
    
    @Before(stages= LifecycleStage.BindingAndValidation, on= {"edit","save","addTrip","close","close2","getTripsByDates","listTripsForEmployee"})
    public void loadEmployee(){
        String id = context.getRequest().getParameter("employee.id");
        if(id == null) return;
        employee = employeeService.retrieveEmp(Long.parseLong(id));
    }
    
    public Resolution edit(){
        log.debug("edit() employee={}",employee);
        return new ForwardResolution("/WEB-INF/jsp/employeeEdit.jsp");
    }
    
    public Resolution save(){
        log.debug("save() employee={}",employee);
        employeeService.updateEmp(employee);
        return new RedirectResolution(this.getClass(),"all");
    }
    
    public Resolution addTrip(){
        log.debug("add Trip employee={}",employee);
        return new ForwardResolution("/WEB-INF/jsp/businessTripCreateEmployee.jsp");
    }
    
    public Resolution createTrip(){
        log.debug(" businessTrip create({})",businessTrip);
        VehicleTO v = vehicleService.retrieve(businessTrip.getVehicle().getId());
        businessTrip.setEmployee(this.employee);
        businessTrip.setVehicle(v);
        businessTrip.setDateOfTrip(new Date());
        businessTripService.create(businessTrip);
        return new ForwardResolution("/WEB-INF/jsp/businessTripForEmployee.jsp");
    }
    
    public Resolution close(){
        String id = context.getRequest().getParameter("businessTrip.id");
        this.businessTrip = businessTripService.retrieve(Long.parseLong(id));
        log.debug("closeTrip employee={},tripp={}",employee,businessTrip);
        return new ForwardResolution("/WEB-INF/jsp/businessTripCloseEmployee.jsp");
    }
    
    public Resolution close2(){
        log.debug("CLOSE TRIP{},kms={}",businessTrip,this.drivenKms);
        BusinessTripTO trip = businessTripService.retrieve(businessTrip.getId());
        businessTripService.cancelAbsolvedTrip(trip, this.drivenKms); 
        return new ForwardResolution("/WEB-INF/jsp/businessTripForEmployee.jsp");
    }
    
    public List<EmployeeTO> getEmployees(){
        if(this.employeePosition != null){
            EmployeePosition tmp = this.employeePosition;
            this.employeePosition = null;
            return this.employeeService.retrieveByCategory(tmp);
        }
        else{
            return employeeService.retrieveAll();
        }
    }
    
    public Resolution getTripsByDates(){
        log.debug("Trips from={} to={},for employee{}",fromDate,toDate,employee);
        return new ForwardResolution("/WEB-INF/jsp/businessTripForEmployee.jsp");
    }

    @Override
    public ActionBeanContext getContext() {
        return context;
    }

    
    @Override
    public void setContext(ActionBeanContext context) {
        this.context = context;
    }

    public EmployeeTO getEmployee() {
        return employee;
    }

    public void setEmployee(EmployeeTO employee) {
        this.employee = employee;
    }
    
    public List<VehicleTO> getVehicles(){
        return vehicleService.retrieveAllVehiclesForPosition(this.employee.getPosition());
    }
    
    public List<BusinessTripTO> getTrips(){
        List<BusinessTripTO> result = businessTripService.retriveEmployeeBusinessTrips(employee);
        if(fromDate != null && toDate != null){
            log.debug(" GET Trips from={} to={},for employee{}",fromDate,toDate,employee);
            List<BusinessTripTO> resultList = businessTripService.retrieveByDates(result, fromDate, toDate);
            fromDate = toDate = null;
            return resultList;
        }
        return result;
    }
}
